﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Net;

namespace Socket_Server
{
    /// <summary>
    /// 服务端监听客户端信息，一旦有发送过来的信息，便立即处理
    /// </summary>
    class Program
    {
        //全局TcpClient
        static TcpClient client;
        //文件流建立到磁盘上的读写流
        static FileStream fs = new FileStream("E:\\abc.jpg", FileMode.Create);
        //buffer
        static int bufferlength = 200;
        static byte[] buffer = new byte[bufferlength];
        //网络流
        static NetworkStream ns;

        static void Main(string[] args)
        {
            ConnectAndListen();
        }

        static void ConnectAndListen()
        {
            //服务端监听任何IP 但是端口号是80的连接
            TcpListener listener = new TcpListener(IPAddress.Any, 99);
            //监听对象开始监听
            listener.Start();
            while (true)
            {
                Console.WriteLine("等待连接");
                //线程会挂在这里，直到客户端发来连接请求
                client = listener.AcceptTcpClient();
                Console.WriteLine("已经连接");
                //得到从客户端传来的网络流
                ns = client.GetStream();
                //如果网络流中有数据
                if (ns.DataAvailable)
                {
                    //同步读取网络流中的byte信息
                    // do
                    //  {
                    //  ns.Read(buffer, 0, bufferlength);
                    //} while (readLength > 0);

                    //异步读取网络流中的byte信息
                    ns.BeginRead(buffer, 0, bufferlength, ReadAsyncCallBack, null);
                }
            }
        }

        /// <summary>
        /// 异步读取
        /// </summary>
        /// <param name="result"></param>
        static void ReadAsyncCallBack(IAsyncResult result)
        {
            int readCount;
            //获得每次异步读取数量
            readCount = client.GetStream().EndRead(result);
            //如果全部读完退出，垃圾回收
            if (readCount < 1)
            {
                client.Close();
                ns.Dispose();
                fs.Dispose();
                return;
            }
            //将网络流中的图片数据片段顺序写入本地
            fs.Write(buffer, 0, 200);
            //再次异步读取
            ns.BeginRead(buffer, 0, 200, ReadAsyncCallBack, null);
        }
    }
}
